// Created by plusminus on 9:16:02 PM - Feb 26, 2009
package org.anddev.arcc;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import org.anddev.arcc.adt.Inconsistency;
import org.anddev.arcc.checkers.DrawableChecker;
import org.anddev.arcc.checkers.StringValuesChecker;

/**
 * @author Nicolas Gramlich
 */
public class ResourceChecker{
	// ===========================================================
	// Constants
	// ===========================================================
	
	private static final char PARSEFLAG_STRINGS = 's';
	private static final char PARSEFLAG_DRAWABLES = 'd';
	private static final String PARSEFLAG_DEFAULT = "" + PARSEFLAG_STRINGS + PARSEFLAG_DRAWABLES;

	// ===========================================================
	// Fields
	// ===========================================================

	// ===========================================================
	// Constructors
	// ===========================================================
	
	public static void main(String[] args) {
		if(args == null || args.length == 0)
			printUsageAndExit();		
		
		/* PArsing will only start if this variable was set. */
		String projectPath = null;
		String parseFlags = null;
		
		for (int i = 0; i < args.length; i += 2) {
			if(args[i].equals("-r")){
				if(i >= args.length){
					printUsageAndExit();
				}else{
					projectPath = args[i+1];
				}
			}else if(args[i].equals("-f")){
				if(i >= args.length){
					printUsageAndExit();
				}else{
					parseFlags = args[i+1];
				}
			}
		}
		
		if(projectPath == null)
			printUsageAndExit();
		
		if(parseFlags == null)
			parseFlags = PARSEFLAG_DEFAULT;

		rResourceParsing(projectPath, parseFlags);
	}

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods from SuperClass/Interfaces
	// ===========================================================

	// ===========================================================
	// Methods
	// ===========================================================

	private static void rResourceParsing(final String pProjectPath, final String pParseFlags) {
		System.out.println("-------------------------");
		
		/* Measure execution-time. */
		final long startMs = System.currentTimeMillis();
		
		/* Kick off the actual parsing. */
		final List<Inconsistency> divs = parseResources(pProjectPath, pParseFlags);
		
		final long endMs = System.currentTimeMillis();
		System.out.println("-------------------------");
		System.out.println("Finished in: " + (endMs - startMs) + " ms");
		System.out.println("");
		System.out.println("-------------------------");
		
		/* Put the results to the console. */
		if(divs.size() == 0){
			System.out.println("No inconsistencies found.");
		}else{
			for (Inconsistency div : divs)
				System.out.println(div);
			
			
			System.out.println("Total number of inconsistencies: " + divs.size());
		}

		System.out.println("-------------------------");
	}

	private static void printUsageAndExit() {
		System.out.println("Usage: -r [res-folder-of-project] -f ['d' (Drawables) |& 's' Strings]");
		System.exit(0);
	}

	private static List<Inconsistency> parseResources(final String pPathname, final String pParseFlags) {
		System.out.println("Parsing: " + pPathname);
		
		final List<Inconsistency> out = new ArrayList<Inconsistency>();
		
		final File projectResourceDir = new File(pPathname);
		if(!projectResourceDir.isDirectory())
			printUsageAndExit();
		
		/* Loop through all the Flags and start the appropriate parsing. */
		final char[] parseFlags = pParseFlags.toCharArray();
		for (char flag : parseFlags) {
			switch(flag){
				case PARSEFLAG_STRINGS:
					out.addAll(parseStringValues(projectResourceDir));
					break;
				case PARSEFLAG_DRAWABLES:
					out.addAll(parseDrawables(projectResourceDir));
					break;
			}
		}
		
		return out;
	}

	private static List<Inconsistency> parseStringValues(final File projectResourceDir) {		
		/* Get all subDirectories starting with "values". */
		final String[] valueDirectories = projectResourceDir.list(new StartsWithFilenameFilter(StringValuesChecker.BASEDIRECTORY));
		
		/* Check for value-inconsistencies. */
		return new StringValuesChecker(projectResourceDir, valueDirectories).run();
	}
	
	private static List<Inconsistency> parseDrawables(final File projectResourceDir) {		
		/* Get all subDirectories starting with "values". */
		final String[] drawableDirectories = projectResourceDir.list(new StartsWithFilenameFilter(DrawableChecker.BASEDIRECTORY));
		
		/* Check for value-inconsistencies. */
		return new DrawableChecker(projectResourceDir, drawableDirectories).run();
	}
	

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================

	private static class StartsWithFilenameFilter implements FilenameFilter {
		private String mStartsWith;
		public StartsWithFilenameFilter(final String pStartsWith) {
			this.mStartsWith = pStartsWith;
		}
		@Override
		public boolean accept(File dir, String name) {
			return name.startsWith(mStartsWith);
		}
	}
}
